package com.lx.permission;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.view.WindowManager;

import androidx.appcompat.app.AlertDialog;

public class PermissionManager {

    private static final PermissionManager mPermissionManager = new PermissionManager();

    private PermissionManager() {
    }

    public static PermissionManager getInstance() {
        return mPermissionManager;
    }

    private final int MSG_RATIONAL = 0x01;
    private final int MSG_REJECT = 0x02;

    private FailedCallBack mFailedCallBack;
    private SuccessCallback mSuccessCallback;

    private String[] mPermissions;
    private Context mContext;


    private IPermissionCallback mIPermissionCallback;
    private int mCallbackId = 0;

    /**
     *
     * @param IPermissionCallback
     * @param callbackId    调用标识，标识被谁调就返回谁的标识
     */
    public void setIPermissionCallback(IPermissionCallback IPermissionCallback, int callbackId) {
        mIPermissionCallback = IPermissionCallback;
        this.mCallbackId = callbackId;
    }


    //要申请权限的回调
    private PermissionCallback mPermissionCallback = new PermissionCallback() {

        @Override
        public void onPermissionGranted() {
//            LogUtil.e("申请权限成功");
//            Toast.makeText(mContext, "权限申请成功--方式1", 0).show();
            if (mIPermissionCallback != null) {
                mIPermissionCallback.granted(mCallbackId);
            }
        }

        @Override
        public void shouldShowRational(String[] rationalPermissons, boolean before) {

            showDialog((Activity) mContext, getPermissionMsg(rationalPermissons, MSG_RATIONAL),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            //重新申请权限
                            requestAgain(mContext, mPermissionCallback);
                        }
                    });
        }

        @Override
        public void onPermissonReject(String[] rejectPermissons) {

            showDialog((Activity) mContext, getPermissionMsg(rejectPermissons, MSG_REJECT),
                    mContext.getString(R.string.dialog_cancel),
                    mContext.getString(R.string.dialog_go_setting),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            //重新申请权限
                            startSettingsActivity(mContext);
                        }
                    }
            );
        }
    };

    private String getPermissionMsg(String[] rationalPermissons, int msgFalg) {

        StringBuilder sb = new StringBuilder();
//        sb.append("需要权限:\n\n");
        sb.append(mContext.getString(R.string.dialog_need_permission) + "\n\n");
        for (int i = 0; i < rationalPermissons.length; i++) {
            sb.append(i + 1).append(".");
            if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_read_external_permission));
            } else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_read_write_external_permission));
            } else if (Manifest.permission.CAMERA.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_camera_permission));
            } else if (Manifest.permission.READ_PHONE_STATE.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_read_phone_status_permission));
            } else if (Manifest.permission.ACCESS_FINE_LOCATION.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_access_fine_location_permission));
            } else if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_access_coarse_location_permission));
            } else if (Manifest.permission.RECORD_AUDIO.equals(rationalPermissons[i])) {
                sb.append(mContext.getString(R.string.dialog_record_audio_permission));
            }
            sb.append("\n");
        }
        if (msgFalg == MSG_REJECT) {
            sb.append(mContext.getString(R.string.dialog_permission_is_prohibit_go_setting));
        }
        return sb.toString();
    }


    public boolean hasRequestPermission(Context context, String[] permissions) {
        return PermissionActivity.hasRequestPermission(context, permissions);
    }


    /**
     * 请求获取权限
     *
     * @param context
     * @param permissions
     */
    public void requestPermission(Context context, String[] permissions) {

        this.mPermissions = permissions;

        PermissionCallback callback02 = checkArguments(context, permissions, mPermissionCallback);

        PermissionActivity.requestPermission(context.getApplicationContext(), permissions, callback02, false);
    }

    /**
     * 方法说明:  检查参数
     * created by liuxiong on 2019/4/29 14:41
     */
    private PermissionCallback checkArguments(Context context, String[] permissions,
                                              PermissionCallback callback) {
        if (context == null) {
            throw new IllegalArgumentException("context can not be null");
        }

        if (!(context instanceof Activity)) {
            throw new IllegalArgumentException("context must be activity");
        }
        this.mContext = context;

        if (mIPermissionCallback == null) {
            throw new IllegalArgumentException("IPermissionCallback can not be null");
        }

        if (permissions == null) {
            throw new IllegalArgumentException("permissions can not be null");
        }
        if (callback == null && mSuccessCallback != null) {
            callback = mSuccessCallback;
        }

        if (callback == null) {
            throw new IllegalArgumentException("PermissionCallback can not be null");
        }

        if (callback instanceof SuccessCallback) {
            mSuccessCallback = (SuccessCallback) callback;

//            LogUtil.e("callback is SuccessCallback");

            /** 如果传入的callback 是 SuccessCallback，那么需要一个PermissionCallback代理一下回调*/
            PermissionCallback callback02 = new PermissionCallback() {
                @Override
                public void onPermissionGranted() {
                    if (mSuccessCallback != null) {
                        mSuccessCallback.onPermissionGranted();
                    }
                }

                @Override
                public void shouldShowRational(String[] rationalPermissons, boolean before) {
                    if (mFailedCallBack != null) {
                        mFailedCallBack.shouldShowRational(rationalPermissons, before);
                    } else {
                        LogUtil.e("没有设置权限申请失败的回调");
                    }
                }

                @Override
                public void onPermissonReject(String[] rejectPermissons) {
                    if (mFailedCallBack != null) {
                        mFailedCallBack.onPermissonReject(rejectPermissons);
                    } else {
                        LogUtil.e("没有设置权限申请失败的回调");
                    }
                }
            };
            return callback02;
        } else {
            return callback;
        }
    }

    /**
     * 方法说明：用户说明后重新申请(用于统一处理失败回调)
     *
     * @param context 应用上下文
     *                create by liuxiong at 2019/4/28 0028 20:40
     */
    public void requestAgain(Context context) {
        //检验参数
        PermissionCallback callback = checkArguments(context, mPermissions, null);
        //启动一个activity申请权限
        PermissionActivity.requestPermission(context.getApplicationContext(), mPermissions, callback, true);
    }

    /**
     * 方法说明：用户说明后重新申请(用于单独处理失败回调)
     *
     * @param context 应用上下文
     *                create by liuxiong at 2019/4/28 0028 20:40
     */
    private void requestAgain(Context context, PermissionCallback callback) {
        //检验参数
        PermissionCallback callback02 = checkArguments(context, mPermissions, callback);
        //启动一个activity申请权限
        PermissionActivity.requestPermission(context.getApplicationContext(), mPermissions, callback02, true);
    }

    /**
     * 方法说明：用户说明后重新申请
     *
     * @param context 应用上下文
     *                create by liuxiong at 2019/4/28 0028 20:40
     */
    @Deprecated
    public void requestAgain(Context context, String[] permissions, PermissionCallback callback) {
        //检验参数
        PermissionCallback callback02 = checkArguments(context, permissions, callback);
        //启动一个activity申请权限
        PermissionActivity.requestPermission(context.getApplicationContext(), permissions, callback02, true);
    }

    /**
     * 方法说明:  设置权限申请失败后的回调（一般是统一处理权限申请失败的时候设置）
     * created by liuxiong on 2019/4/29 14:26
     */
    public void setFailedCallBack(FailedCallBack failedCallBack) {
        this.mFailedCallBack = failedCallBack;
    }

    /**
     * 方法说明：弹出一个dialog，展示一条 message
     * create by liuxiong at 2019/4/28 0028 20:40
     */
    private void showDialog(final Activity activity, String
            message, DialogInterface.OnClickListener positiveListener) {

        showDialog(activity, message, null, null, positiveListener);
    }

    /**
     * 方法说明：弹出一个dialog，展示一条 message
     * create by liuxiong at 2019/4/28 0028 20:40
     */
    private void showDialog(final Activity activity, String message, String
            negativeButtonText, String positiveButtonText,
                            DialogInterface.OnClickListener positiveListener) {
        if (message == null) {
            LogUtil.e("message==null");
        }
        if (negativeButtonText == null) {
            negativeButtonText = activity.getResources().getString(R.string.dialog_cancel);
        }
        if (positiveButtonText == null) {
            positiveButtonText = activity.getResources().getString(R.string.dialog_comfirm);
        }
        if (positiveListener == null) {
            positiveListener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            };
        }
        AlertDialog alterDialog = new AlertDialog.Builder(activity).setMessage(message).setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
            }
        }).setPositiveButton(positiveButtonText, positiveListener).show();
        WindowManager.LayoutParams params = alterDialog.getWindow().getAttributes();
        params.width = dip2px(mContext, 350);
        alterDialog.getWindow().setAttributes(params);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    private int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    private int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 跳转到当前设置里当前app页面
     *
     * @param context
     */
    private void startSettingsActivity(Context context) {
        Uri packageURI = Uri.parse("package:" + context.getPackageName());
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
}
